<template>
  <div class="hexian"></div>
</template>

<script>
const width = 250;
const height = 250;
const colors = [
  "#9EB6C8",
  "#9EA6B0",
  "#9EA6B3",
  "#B39696",
  "#CDBAA7",
  "#DBC7A7",
  "#B5BFB6",
];
const nodesNum = 7;

const outerR = Math.min(width, height) / 2;
const innerR = outerR - 10;
const padAngle = (2 * Math.PI) / 200;
export default {
  name: "hexian",
  data() {
    return {
      datas: [],
      data: [],
      similary: [],
      similarys: [],
    };
  },
  methods: {
    draw() {
      const that = this;
      const chords = d3.chord().padAngle(padAngle)(this.similary);
      const svg = d3
        .select(".hexian")
        .append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", `translate(${width / 2}, ${height / 2})`);
      drawGroups(); // 绘制节点
      drawChords(); // 绘制弦图

      function drawGroups() {
        function debounce(fn, time) {
          let timeId = null;
          return function () {
            const context = this;
            const event = d3.event;
            timeId && clearTimeout(timeId);
            timeId = setTimeout(function () {
              d3.event = event;
              fn.apply(context, arguments);
            }, time);
          };
        }

        const groups = chords.groups; // 节点数组
        const arc = d3
          .arc()
          .innerRadius(innerR - 20)
          .outerRadius(outerR - 15);

        svg
          .append("g")
          .attr("class", "groups")
          .selectAll("g")
          .data(groups)
          .enter()
          .append("g")
          .attr("class", "group")
          .append("path")
          .attr("d", (d) => {
            return arc(d);
          })
          .attr("fill", (_, i) => colors[i])
          .on("mouseover", function (_, i) {
            const e = d3.event;
            const position = d3.mouse(svg.node());
            e.target.style.cursor = "hand";

            svg
              .append("text")
              .classed("tip", true)
              .attr("x", position[0] + 5)
              .attr("y", position[1])
              .attr("fill", "#72565B")
              .attr("font-family", '"华文行楷", "STXingkai", serif')
              .text(that.data[i]);

            d3.select(this)
              .transition()
              .duration(250)
              .attr("fill", d3.rgb(colors[i]).darker());
          })
          .on("mouseout", function (_, i) {
            d3.select(this).transition().duration(250).attr("fill", colors[i]);
            d3.select(".tip").remove();
          })
          .on(
            "mousemove",
            debounce(function () {
              const position = d3.mouse(svg.node());
              d3.select(".tip")
                .attr("x", position[0] + 5)
                .attr("y", position[1] - 5);
            }, 6)
          );
      }

      function drawChords() {
        const ribbon = d3.ribbon().radius(innerR - 20);

        svg
          .append("g")
          .attr("class", "chord")
          .selectAll("path")
          .data(chords)
          .enter()
          .append("path")
          .attr("d", ribbon)
          .attr("opacity", 0.4)

          .attr("fill", ({ source: { index } }) => colors[index])
          .attr("stroke", "none")
          .on("mouseover", function ({ source: { index } }, i) {
            d3.select(this)
              .transition()
              .duration(250)
              .attr("fill", d3.rgb(colors[index]).darker());

            const e = d3.event;
            const position = d3.mouse(svg.node());
            e.target.style.cursor = "hand";
            svg
              .append("text")
              .classed("tip", true)
              .attr("x", position[0] + 5)
              .attr("y", position[1])
              .attr("fill", "#72565B")
              .attr("font-family", '"华文行楷", "STXingkai", serif')
              .text("相似度: " + that.similarys[i]);
          })
          .on("mouseout", function ({ source: { index } }) {
            d3.select(this)
              .transition()
              .duration(250)
              .attr("fill", colors[index]);
            d3.select(".tip").remove();
          });
      }
    },
    changedata() {
      for (let i = 7; i > 0; i--) {
        let similary = this.similary[7 - i].concat();
        this.similarys = this.similarys.concat(similary.splice(-i + 1, i - 1));
      }
    },
    changedatas(value) {
      this.data = this.datas[value];
    },
    pop(similary) {
      this.similary = similary;
      d3.select(".hexian").selectAll("*").remove();
      this.draw();
      this.changedata();
    },
  },
  mounted() {
    this.$bus.$on("changed", (value) => {
      this.changedata();
    });
    this.$bus.$on("changeds", (value) => {
      this.changedatas(value);
    });
    this.$axios.get("/dynasty_works.json").then((res) => {
      this.datas = res.data;
      this.draw();
      this.changedata();
      this.changedatas("东吴");
    });
  },
};
</script>

<style>
svg {
  border-radius: 4px;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
}
</style>
